#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <linux/videodev.h>

#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>

#include <sys/time.h>
#include <time.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"

#include "encode.h"
#include "decode.h"
#include "yuv2rgb.h"
#include "capture.h"
#include "scale_data.h"
#include "save_image.h"
#include "global.h"
#include "util.h"
#include "draw_text.h"

#define LIST_COLUMN 4
#define DIRECT_VIEW_MODE 144
#define SEARCH_VIEW_MODE 145


struct image_info {
	struct camera* cam;
	struct mpeg_encode* me;
	struct mpeg_decode* md;
	int x;
	int y;
	int image_draw;
	int cam_num;
	pthread_t capture_thread;
	pthread_t encode_thread;
	pthread_t decode_thread;
	char cam_place[100];
};

struct play_info* p_play_info = NULL;

GdkPixmap* pixmap;
GtkWidget* image;
GtkComboBox* start_combo[4];
GtkComboBox* end_combo[4];
GtkCList* file_list;
GtkVBox* control_box;
GtkWidget* check_camera[CAM_NUM];
GtkWidget* check_screen1;
GtkWidget* check_screen4;
GtkTextBuffer* event_text;
GtkTextView* event_log;
GtkRange* hour_range;
GtkRange* min_range;
GtkDialog* search_dialog;

gchar* selected_text[LIST_COLUMN];

struct image_info img_info[CAM_NUM];



int area_view_mode = 2;
int view_mode = DIRECT_VIEW_MODE;
int is_record = 1;
int is_draw_place = 1;
int is_draw_time = 1;
static int decode_thread_count = 0;
pthread_mutex_t encode_close_mutex;

void 
update_event_log(char* event) 
{
	char text[10000];
	gchar* temp;
	int  last;
	GtkTextIter start, end;
	struct tm *tmv;
	time_t t;
	
	time(&t);
	tmv = localtime(&t);

	last = gtk_text_buffer_get_line_count(event_text);


	gtk_text_buffer_get_iter_at_line(event_text, &start, 0);
	gtk_text_buffer_get_iter_at_line(event_text, &end, last);	


	temp = gtk_text_buffer_get_text(event_text, &start, &end, FALSE);

	if (strlen(temp) > 9500) {
		temp = strchr(temp, '\n') + 1;
		temp = strchr(temp, '\n') + 1;
	}
	strcpy(text, temp);
	sprintf(text, "%s%d년%d월%d일%d시%d분%d초:\n%s\n", text,
			tmv->tm_year+1900, tmv->tm_mon+1, tmv->tm_mday,
			tmv->tm_hour, tmv->tm_min, tmv->tm_sec, event);

	gtk_text_buffer_set_text(event_text, text, strlen(text));
	gtk_text_view_set_buffer(event_log, event_text);

}

int
set_next_pos(int* pos, int chan)
{
	unsigned char temp;
	int i;

	fseek(p_play_info->f[chan], *pos/8, SEEK_SET);
	fread(&temp, 1, 1, p_play_info->f[chan]);

	if (temp & 0x80 >> (*pos % 8)) {
		if (move_end_pos(p_play_info->f[chan], pos) == -1) {
			fprintf(stderr, "don't exist next play\n");
			return -1;
		}
	}
	return move_next_pos(p_play_info->f[chan], pos);

}
int 
set_end_pos(int* pos, int chan)
{
	unsigned char temp;
	int i;

	fseek(p_play_info->f[chan], *pos/8, SEEK_SET);
	fread(&temp, 1, 1, p_play_info->f[chan]);

	if (temp & 0x80 >> (*pos % 8)) {
		return move_end_pos(p_play_info->f[chan], pos);
	}
	return -1;
}
int
set_start_pos(int* pos, int chan)
{
	unsigned char temp;
	int i;

	fseek(p_play_info->f[chan], (*pos)/8, SEEK_SET);
	fread(&temp, 1, 1, p_play_info->f[chan]);

	if (temp & 0x80 >> (*pos % 8)) {
		return move_start_pos(p_play_info->f[chan], pos);
	}
	return -1;
}
int
set_previous_pos(int* pos, int chan)
{
	unsigned char temp;
	int i;

	fseek(p_play_info->f[chan], *pos/8, SEEK_SET);
	fread(&temp, 1, 1, p_play_info->f[chan]);

	if (temp & 0x80 >> (*pos % 8)) {
		if (move_start_pos(p_play_info->f[chan], pos) == -1) {
			fprintf(stderr, "don't exist previous play\n");
			return -1;
		}
	}
	return move_previous_pos(p_play_info->f[chan], pos);


}

int
update_decode_pos(int chan)
{
	int i_pos;
	int pos = p_play_info->cur_pos[chan];
	int hour;
	int len;

	p_play_info->frame_count[chan] = 0;
	hour = p_play_info->hour[chan] = pos / 3600;
	p_play_info->min[chan] = (pos - (hour * 3600))/60;
	p_play_info->sec[chan] = (pos - (hour * 3600))%60;
 
	fseek(p_play_info->f[chan], 10800 + pos*sizeof(int), SEEK_SET);
	fread(&i_pos, sizeof(int), 1, p_play_info->f[chan]);
	if (i_pos == -1) {
		if (set_next_pos(&pos, chan) != -1) {
			fseek(p_play_info->f[chan], 10800 + pos*sizeof(int), SEEK_SET);
			fread(&i_pos, sizeof(int), 1, p_play_info->f[chan]);
			p_play_info->cur_pos[chan] = pos;
		} else
			return -1;
			
		
	}
	pthread_mutex_lock(&img_info[chan].md->pos_mutex);
	hunter_decode_pos_set(img_info[chan].md, i_pos);
	pthread_mutex_unlock(&img_info[chan].md->pos_mutex);

	return 1;

}
int 
update_decode_pos2(int chan)
{
	int i_pos;
	int pos = p_play_info->cur_pos[chan];
	int hour;
	
	p_play_info->frame_count[chan] = 0;
	hour = p_play_info->hour[chan] = pos / 3600;
	p_play_info->min[chan] = (pos - (hour * 3600))/60;
	p_play_info->sec[chan] = (pos - (hour * 3600))%60;
 
	fseek(p_play_info->f[chan], 10800 + pos*sizeof(int), SEEK_SET);
	fread(&i_pos, sizeof(int), 1, p_play_info->f[chan]);
	if (i_pos == -1) {
		if (set_previous_pos(&pos, chan) != -1){
			fseek(p_play_info->f[chan], 10800 + pos*sizeof(int), SEEK_SET);
			fread(&i_pos, sizeof(int), 1, p_play_info->f[chan]);
			p_play_info->cur_pos[chan] = pos;
		} else
			return -1;
		
	}
	pthread_mutex_lock(&img_info[chan].md->pos_mutex);
	hunter_decode_pos_set(img_info[chan].md, i_pos);
	pthread_mutex_unlock(&img_info[chan].md->pos_mutex);

	return 1;

}
void 
update_range_pos()
{
	int hour = p_play_info->cur_pos[0]/3600;
	GtkAdjustment* hour_adj;
	GtkAdjustment* min_adj;

	gdk_threads_enter();
	gtk_range_set_value(hour_range, p_play_info->cur_pos[0]);
	gtk_range_set_value(min_range, p_play_info->cur_pos[0] - (hour * 3600));
	gdk_threads_leave();


}
void 
exit_decode_thread() {
	int i;

	if (p_play_info) {	
		for(i = 0; i < CAM_NUM; i++) {
			p_play_info->state[i] = EXIT_PLAY;
		}
	}
}
void 
draw_text_place(unsigned char* image_data, int cam_num)
{
	draw_text(image_data, width/30, height/20, img_info[cam_num].cam_place);

}
void
draw_text_time(unsigned char* image_data, int cam_num)
{
	struct tm* tmv;
	time_t t;
	char temp[100];


	switch(view_mode) {
		case DIRECT_VIEW_MODE:
			time(&t);
			tmv = localtime(&t);
			sprintf(temp, "%d-%d-%d %d:%d:%d",
				       tmv->tm_year+1900, tmv->tm_mon+1,
				       tmv->tm_mday, tmv->tm_hour, tmv->tm_min,
				       tmv->tm_sec);
			draw_text(image_data, (int)width/2, height/20, temp);
			

			break;
		case SEARCH_VIEW_MODE:
			sprintf(temp, "%d-%d-%d %d:%d:%d",
					p_play_info->year, p_play_info->mon, p_play_info->day,
					p_play_info->hour[cam_num], p_play_info->min[cam_num],
					p_play_info->sec[cam_num]);
			draw_text(image_data, (int)width/2, height/20, temp);

			break;
	}

}
void
redraw_image(unsigned char* image_data, int x, int y, int cam_num)
{
	
	GdkRectangle rect;
	unsigned char* out_data;
	int split_width, split_height;
	int full_width = image->allocation.width;
	int full_height = image->allocation.height;

	split_width = full_width/area_view_mode;
	split_height = full_height/area_view_mode;

	out_data = (unsigned char*) malloc(split_width*split_height*3);

	if( area_view_mode == 1) {
		rect.x = 0;
		rect.y = 0;
	} else {	
		rect.x = full_width - full_width/x*1.0;
		rect.y = full_height - full_height/y*1.0;
	}
	rect.width = split_width;
	rect.height = split_height;

	if (is_draw_place) 
		draw_text_place(image_data, cam_num);
	if (is_draw_time)
		draw_text_time(image_data, cam_num);
	scale_data(image_data, out_data, width, height, split_width, split_height);

	gdk_threads_enter();
	gdk_draw_rgb_image(pixmap, image->style->white_gc, rect.x, rect.y, split_width, split_height,
			GDK_RGB_DITHER_NORMAL, out_data, split_width*3);
	gdk_threads_leave();

	free(out_data);

	gdk_threads_enter();
	gtk_widget_draw(image, &rect);
	gdk_flush();
	gdk_threads_leave();

}


void
encode_file(struct image_info* img_info)
{
	struct mpeg_encode* me = img_info->me;
	struct camera* cam = img_info->cam;
	struct tm *tmv;
	time_t t;

	time(&t);
	tmv = localtime(&t);

	img_info->me->pos = tmv->tm_hour*3600 + tmv->tm_min*60 + tmv->tm_sec; 

	while(1) {
		if( !is_record) {
			pthread_mutex_lock(&encode_close_mutex);
			hunter_encode_close(me);
			pthread_mutex_unlock(&encode_close_mutex);
			me = img_info->me = NULL;
			break;
		}
		if ( cam && cam->is_update) {
			hunter_encode_put(me, cam->pic_data);
			cam->is_update = 0;
		}
		usleep(1);

	}
}

void
capture_cam(struct image_info* img_info)
{
	struct timeval tv;

	unsigned long start_time, current_time;
	int i_frame_count = 0;
	int frame_count = 0;

	struct camera* cam = img_info->cam;
	int remain, ret, encode_wait = DIRECT_VIEW_FPS/ENCODE_FPS;
	char temp[100];

	gettimeofday(&tv, NULL);
	start_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);

	while(1) {
		if (cam) {
			ret = capture(cam);
			if (ret == -1) {
				capture_close(cam);
				cam = NULL;
			} else {
				
				frame_count++;
				if (frame_count % encode_wait == 0)
					cam->is_update = 1;
				if (frame_count % DIRECT_VIEW_FPS == 0) {
					i_frame_count ++;
					frame_count = 0;
				}
				yuv2rgb(cam->pic_data, cam->rgb_data);
				if(view_mode == DIRECT_VIEW_MODE && img_info->image_draw)
					redraw_image(cam->rgb_data, img_info->x, img_info->y, cam->cam_num);
			}
		} else if (!cam){
			
			sprintf(temp, "/dev/video%d", img_info->cam_num);
			img_info->cam = camera_alloc(temp, img_info->cam_num);
			if (img_info->cam) {
				ret = capture_init(img_info->cam);
				if (ret == -1) {
					capture_close(cam);
					cam = NULL;
				} else
					cam = img_info->cam;
			} else {
				capture_close(cam);
				cam = NULL;
			}
			
		}
		gettimeofday(&tv, NULL);
		current_time  = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
		remain = (start_time + i_frame_count*1000 + frame_count*100/(DIRECT_VIEW_FPS/10.0)) - current_time;
		if (remain > 0)
			usleep(remain*1000);

	}
}
int
decode (struct image_info* img_info)
{
	unsigned char* data = NULL;
	struct mpeg_decode* md = img_info->md;
	int cam_num = img_info->cam_num;

	pthread_mutex_lock(&img_info->md->pos_mutex);
	hunter_decode_get(md, &data);
	pthread_mutex_unlock(&img_info->md->pos_mutex);
	if (data) {
		p_play_info->frame_count[cam_num]++;
		if (p_play_info->frame_count[cam_num] % 30 == 0) {
			p_play_info->cur_pos[cam_num]++;
			if (cam_num == 0) {
				update_range_pos();
			}
			p_play_info->frame_count[cam_num] = 0;
		}
		yuv2rgb(data, md->rgb_data);
		free(data);
		return 1;
	}
	return -1;
}
void
decode_file(struct image_info* img_info)
{
	struct timeval tv;
	unsigned long start_time, current_time;
	struct mpeg_decode* md = img_info->md;
	int remain;
	int ret;
	int cam_num = img_info->cam_num;
	

	gettimeofday(&tv, NULL);
	start_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);

	while(1) {
		switch(p_play_info->state[cam_num]) {
			case PLAY:
				if (decode(img_info) == 1) {
					if(img_info->image_draw && p_play_info->frame_count[cam_num]%3 == 0)
						redraw_image(md->rgb_data, img_info->x, img_info->y, img_info->cam_num);	
		
					gettimeofday(&tv, NULL);
					current_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
		
					remain = (100000 / 3) - (current_time - start_time)*1000;
					if (remain > 0)
						usleep(remain);
		
					gettimeofday(&tv, NULL);
					start_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
				}// else 
					//memset(md->rgb_data, '\0', DEFAULT_WIDTH*DEFAULT_HEIGHT*3);
					//free(md->rgb_data);
				break;
			case WAIT:
				if(img_info->image_draw)
					redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);	
				break;
			case STOP:
				set_start_pos(&p_play_info->cur_pos[cam_num], cam_num);
				update_decode_pos(cam_num);
				if (decode(img_info) == 1) {
					if(img_info->image_draw)
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);
				}	
				break;
			case NEXT_STEP:
				if (decode(img_info) == 1) {
					if(img_info->image_draw && p_play_info->frame_count[cam_num]%3 == 0) {
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);	
						p_play_info->state[cam_num] = WAIT;
					}
				}
				break;
			case MOVE_START_POS:
				set_start_pos(&p_play_info->cur_pos[cam_num], cam_num);
				update_decode_pos(cam_num);
				if (decode(img_info) == 1) {
					if(img_info->image_draw)
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);
				}
				break;
			case MOVE_END_POS:
				set_end_pos(&p_play_info->cur_pos[cam_num], cam_num);
				update_decode_pos(cam_num);
				if (decode(img_info) == 1) {
					if(img_info->image_draw)
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);
				} 
				break;
			case NEXT_PLAY:
				ret = set_next_pos(&p_play_info->cur_pos[cam_num], cam_num);
				update_decode_pos(cam_num);
				if (ret == -1) {
					p_play_info->state[cam_num] = WAIT;
					break;
				}
				p_play_info->state[cam_num] = PLAY;
				break;
			case FF_PLAY:
				if (decode(img_info) == 1) {
					p_play_info->cur_pos[cam_num]++;
					update_decode_pos(cam_num);
					if(img_info->image_draw)
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);

					gettimeofday(&tv, NULL);
					current_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
		
					remain = (500000 / 3) - (current_time - start_time)*1000;
					if (remain > 0)
						usleep(remain);
		
					gettimeofday(&tv, NULL);
					start_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
				} 
				break;
			case REV_FF_PLAY:
				if (decode(img_info) == 1) {
					p_play_info->cur_pos[cam_num]--;
					update_decode_pos2(cam_num);
					if(img_info->image_draw)
						redraw_image(md->rgb_data, img_info->x, img_info->y, cam_num);

					gettimeofday(&tv, NULL);
					current_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
		
					remain = (500000 / 3) - (current_time - start_time)*1000;
					if (remain > 0)
						usleep(remain);
		
					gettimeofday(&tv, NULL);
					start_time = (long)tv.tv_sec*1000 + (tv.tv_usec/1000);
				}
				break;
			case NON_PLAY:
				break;
			case EXIT_PLAY:	
				if (md) {
					hunter_decode_close(md);
					img_info->md = NULL;
				}
				fclose(p_play_info->f[cam_num]);
				img_info[cam_num].decode_thread = 0;
				decode_thread_count--;
				if (decode_thread_count == 0) {
					free(p_play_info);
					p_play_info = NULL;
				}
				return;
				break;
		
		}
		usleep(1);
	}
}


gboolean
on_draw_area_configure_event           (GtkWidget       *widget,
                                        GdkEventConfigure *event,
                                        gpointer         user_data)
{

	if (pixmap)
		g_object_unref(pixmap);

	pixmap = gdk_pixmap_new(widget->window, widget->allocation.width,
			widget->allocation.height, -1);
	gdk_draw_rectangle(pixmap, widget->style->white_gc, TRUE, 0, 0,
			widget->allocation.width,
			widget->allocation.height);


  return TRUE;
}


gboolean
on_draw_area_expose_event              (GtkWidget       *widget,
                                        GdkEventExpose  *event,
                                        gpointer         user_data)
{

	gdk_draw_drawable(widget->window,
			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
			pixmap,
			event->area.x, event->area.y,
			event->area.x, event->area.y,
			event->area.width, event->area.height);

  return FALSE;
}

void 
encode_start()
{
	// 현재 시간에 해당하는 파일명 가져오기
	char *file;
	char index_file[1024];
	int re, i;


	update_event_log("record start");
	is_record = 1;
	avcodec_init();
	avcodec_register_all();

	for (i = 0; i < CAM_NUM; i ++) {
		if(img_info[i].cam) {
			file = get_file_name(img_info[i].cam->cam_num, index_file);
			img_info[i].me = hunter_encode_alloc(file, index_file);
			free(file);

			hunter_encode_init(img_info[i].me);

			re = pthread_create(&img_info[i].encode_thread, NULL, (void*)&encode_file, (struct image_info*)&img_info[i]);
			if (re == 0)
				g_print("pthread create\n");
			else
				g_print("pthread create fail\n");
		}
	}

}


void
on_capture_button_clicked              (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;
	char temp[100];

	for (i = 0; i < CAM_NUM; i++) {
		if(img_info[i].cam) {
			save_image(img_info[i].cam->rgb_data, img_info[i].cam_num);
			sprintf(temp, "capture : cam %d", i+1);
			update_event_log(temp);
		}
	}

	

}

void
on_search_button_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{

	GtkWidget* search;

	search = create_search_dialog();
	gtk_widget_show(search);
}

void
on_setup_button_clicked                (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkWidget* setup;
	GtkWidget* place_check;
	GtkWidget* time_check;
	
	setup = create_setup_dialog();

	place_check = (GtkWidget*)lookup_widget((GtkWidget*)setup, "setup_place_check");
	time_check = (GtkWidget*)lookup_widget((GtkWidget*)setup, "setup_time_check");

	if (is_draw_place)	
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(place_check), TRUE);
	if (is_draw_time)	
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(time_check), TRUE);
	
	gtk_widget_show(setup);

}


void
on_state_button_clicked                (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkWidget* state;

	state = create_state_dialog();
	gtk_widget_show(state);

}

void
on_find_button_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
	gchar* selected_start, *selected_end;
	int start = 0, end = 0, i;


	for (i = 0; i < CAM_NUM; i ++) {
		selected_start = gtk_combo_box_get_active_text(start_combo[i]);
		selected_end = gtk_combo_box_get_active_text(end_combo[i]);
		if (i == 0) {
			start = atoi(selected_start);
			end = atoi(selected_end);
		} else {
			start = (start * 100) + atoi(selected_start);
			end = (end * 100) + atoi(selected_end);

		}
	}
	
	gtk_clist_clear(file_list);
	set_file_info(file_list, start, end);
}


void
on_search_cancel_button_enter          (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkDialog* search_dialog;

	search_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "search_dialog");
	gtk_widget_destroy((GtkWidget*)search_dialog); 
}

void set_search (void)
{
	gchar text[LIST_COLUMN][50];
	gchar path[512];
	void **p;
	int start_time;
	int re, i;
	int i_pos;


	while(p_play_info) {
		usleep(10);
	}

	if (view_mode == DIRECT_VIEW_MODE) {
		gdk_threads_enter();
		update_event_log("change search mode");
		gdk_flush();
		gdk_threads_leave();
	}

	av_register_all();

	memset(path, '\0', 512);
	for (i = 0; i < LIST_COLUMN; i++) {
		memset(text[i], '\0', 50);
		strcpy(text[i], selected_text[i]);
	}

	view_mode = SEARCH_VIEW_MODE;

	p_play_info = (struct play_info*)malloc(sizeof(struct play_info));

	sprintf(path, "%s/%s", "/hunter_data", text[0]); 

	hunter_parse_date(text[0], &p_play_info->year, &p_play_info->mon, &p_play_info->day);

	gdk_threads_enter();
	gtk_widget_show((GtkWidget*)control_box);
	gdk_threads_leave();

	start_time  = parse_time(text[1]);
	set_play_info(p_play_info, path, start_time);

	for (i = 0; i < CAM_NUM; i++) {

		img_info[i].md = hunter_decode_alloc(p_play_info->file_name[i]);
		re = hunter_decode_init(img_info[i].md);
		if (re != -1) {
			update_decode_pos(i);

			re = pthread_create(&img_info[i].decode_thread, NULL, (void*)&decode_file, (struct image_info*)&img_info[i]);
			decode_thread_count++;
			if (re == 0)
				g_print("pthread create\n");
			else 
				g_print("pthread create fail\n");
		} else {
			img_info[i].decode_thread = 0;
			hunter_decode_close(img_info[i].md);
			img_info[i].md = NULL;
		}

	}

	selected_text[0] = NULL;
	gdk_threads_enter();
	gtk_widget_destroy((GtkWidget*)search_dialog); 
	gdk_threads_leave();

}
void
on_search_ok_button_clicked            (GtkButton       *button,
                                        gpointer         user_data)
{

	gchar text[LIST_COLUMN][20];
	int re;
	pthread_t search_thread;


	search_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "search_dialog");

	if (selected_text[0]) {
		exit_decode_thread();
		re = pthread_create(&search_thread, NULL, (void*)&set_search, NULL);
		if (re == 0)
			g_print("pthread create\n");
		else 
			g_print("pthread create fail\n");
	}


}

void
on_file_list_select_row                (GtkCList        *clist,
                                        gint             row,
                                        gint             column,
                                        GdkEvent        *event,
                                        gpointer         user_data)
{
	int col;

	for (col = 0; col < LIST_COLUMN; col++) {
		gtk_clist_get_text(clist, row, col, &selected_text[col]);
	}

}





void
on_hunter_show                         (GtkWidget       *widget,
                                        gpointer         user_data)
{
	int re = 0, i;
	char temp[100];


	width = DEFAULT_WIDTH;
	height = DEFAULT_HEIGHT;
	
	event_text = gtk_text_buffer_new(NULL);
	event_log = (GtkTextView*)lookup_widget((GtkWidget*)widget, "event_log");
	image = (GtkWidget*)lookup_widget((GtkWidget*)widget, "draw_area");
	control_box = (GtkVBox*)lookup_widget((GtkWidget*)widget, "vbox6");
	
	check_camera[0] = (GtkWidget*)lookup_widget((GtkWidget*)widget, "camera1_check");
	check_camera[1] = (GtkWidget*)lookup_widget((GtkWidget*)widget, "camera2_check");
	check_camera[2] = (GtkWidget*)lookup_widget((GtkWidget*)widget, "camera3_check");
	check_camera[3] = (GtkWidget*)lookup_widget((GtkWidget*)widget, "camera4_check");
	check_screen1 = (GtkWidget*)lookup_widget((GtkWidget*)widget, "_1split_screen");
	check_screen4 = (GtkWidget*)lookup_widget((GtkWidget*)widget, "_4split_screen");

	hour_range = (GtkRange*)lookup_widget((GtkWidget*)widget, "hscale1");
	min_range = (GtkRange*)lookup_widget((GtkWidget*)widget, "hscale2");

	gtk_widget_hide((GtkWidget*)control_box);

	yuv2rgb_init();

	strcpy(img_info[0].cam_place, "Lab 101");
	strcpy(img_info[1].cam_place, "Lab 102");
	strcpy(img_info[2].cam_place, "Lab 103");
	strcpy(img_info[3].cam_place, "Lab 305");

	for (i = 0; i < CAM_NUM; i++) {
		sprintf(temp, "/dev/video%d", i);
		img_info[i].cam = camera_alloc(temp, i);
		img_info[i].me = NULL;
		img_info[i].md = NULL;
		img_info[i].image_draw = 1;
		img_info[i].cam_num = i;
		img_info[i].x = (i % 2) + 1;
		img_info[i].y = (i / 2) + 1;

		if (img_info[i].cam) {
			capture_init(img_info[i].cam);
		}
	}
	for (i = 0; i < CAM_NUM; i++) {
		re = pthread_create(&img_info[i].capture_thread, NULL, (void*)&capture_cam, (struct image_info*)&img_info[i]);
		if (re == 0)
			g_print("pthread create\n");
		else
			g_print("pthread create fail\n");
	}
	
	pthread_mutex_init(&encode_close_mutex, NULL);
	encode_start();
	update_event_log("hunter start");


}
void
on_hunter_destroy                      (GtkObject       *object,
                                        gpointer         user_data)
{

	
	gtk_main_quit();

}


void
on_record_button_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{

	if (!is_record) {
		pthread_mutex_init(&encode_close_mutex, NULL);
		encode_start();
	} else {
		is_record = 0;
		update_event_log("record end");

	}

}
void
on_4split_screen_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{

	area_view_mode = 2;
	img_info[0].image_draw = 1;
	img_info[1].image_draw = 1;
	img_info[2].image_draw = 1;
	img_info[3].image_draw = 1;
}


void
on_1split_screen_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	area_view_mode = 1;
	for (i = 0; i < CAM_NUM; i++) {
		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_camera[i])))
			img_info[i].image_draw = 1;
		else
			img_info[i].image_draw = 0;
	}
}


void
on_camera1_check_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen1), TRUE);
	area_view_mode = 1;
	img_info[0].image_draw = 1;
	img_info[1].image_draw = 0;
	img_info[2].image_draw = 0;
	img_info[3].image_draw = 0;

}
void
on_camera2_check_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen1), TRUE);
	area_view_mode = 1;
	img_info[0].image_draw = 0;
	img_info[1].image_draw = 1;
	img_info[2].image_draw = 0;
	img_info[3].image_draw = 0;
}
void
on_camera3_check_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen1), TRUE);
	area_view_mode = 1;
	img_info[0].image_draw = 0;
	img_info[1].image_draw = 0;
	img_info[2].image_draw = 1;
	img_info[3].image_draw = 0;
}


void
on_camera4_check_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen1), TRUE);

	area_view_mode = 1;
	img_info[0].image_draw = 0;
	img_info[1].image_draw = 0;
	img_info[2].image_draw = 0;
	img_info[3].image_draw = 1;
}





void
on_hscale1_value_changed               (GtkRange        *range,
                                        gpointer         user_data)
{

}


void
on_hscale2_value_changed               (GtkRange        *range,
                                        gpointer         user_data)
{
	int hour, min;
	int i;


	hour = (int) gtk_range_get_value(hour_range);
	min = (int) gtk_range_get_value(min_range);
	
	hour /= 3600;

	for (i = 0; i < CAM_NUM; i++) {
		if (img_info[i].md) {
			p_play_info->cur_pos[i] = hour*3600 + min;
			update_decode_pos(i);

		}
	}
	gtk_widget_draw(GTK_WIDGET(range), NULL);

}




void
on_change_mode_button_clicked          (GtkButton       *button,
                                        gpointer         user_data)
{
	exit_decode_thread();
	gtk_widget_hide((GtkWidget*)control_box);
	view_mode = DIRECT_VIEW_MODE;
	update_event_log("change direct mode");
}


void
on_calendar_button_clicked             (GtkButton       *button,
                                        gpointer         user_data)
{

	GtkWidget* calendar;

	calendar = create_calendar_dialog();
	gtk_widget_show(calendar);
}



void
on_calendar_cancel_button_clicked      (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkDialog* calendar_dialog;

	calendar_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "calendar_dialog");
	gtk_widget_destroy((GtkWidget*)calendar_dialog); 

}


void
on_calendar_ok_button_clicked          (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkCalendar* calendar;
	GtkDialog* calendar_dialog;
	gint year, mon, day;

	calendar_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "calendar_dialog");

	calendar = (GtkCalendar*)lookup_widget((GtkWidget*)button, "calendar");

	gtk_calendar_get_date(calendar, &year, &mon, &day);
	g_print("year: %d, mon: %d, day: %d\n", year, mon+1, day);



	gtk_widget_destroy((GtkWidget*)calendar_dialog); 

}


void
on_setup_cancel_button_clicked         (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkDialog* setup_dialog;

	setup_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "setup_dialog");
	gtk_widget_destroy((GtkWidget*)setup_dialog); 
}


void
on_setup_ok_button_clicked             (GtkButton       *button,
                                        gpointer         user_data)
{
	GtkWidget* place_check;
	GtkWidget* time_check;
	GtkDialog* setup_dialog;


	place_check = (GtkWidget*)lookup_widget((GtkWidget*)button, "setup_place_check");
	time_check = (GtkWidget*)lookup_widget((GtkWidget*)button, "setup_time_check");

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(place_check))){
		is_draw_place = 1;
	} else {
		is_draw_place = 0;
	}

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(time_check))) {
		is_draw_time = 1;
	} else {
		is_draw_time = 0;
	}

	setup_dialog = (GtkDialog*)lookup_widget((GtkWidget*)button, "setup_dialog");
	gtk_widget_destroy((GtkWidget*)setup_dialog); 
}




void
on_rev_ff_button_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = REV_FF_PLAY;

}


void
on_play_button_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = PLAY;

}


void
on_wait_button_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = WAIT;

}


void
on_stop_button_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = STOP;

}


void
on_rev_play_button_clicked             (GtkButton       *button,
                                        gpointer         user_data)
{


}


void
on_ff_button_clicked                   (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = FF_PLAY;



}


void
on_previous_rev_play_button_clicked    (GtkButton       *button,
                                        gpointer         user_data)
{

}


void
on_move_startpos_button_clicked        (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = MOVE_START_POS;


}


void
on_previous_step_button_clicked        (GtkButton       *button,
                                        gpointer         user_data)
{

}


void
on_next_step_button_clicked            (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = NEXT_STEP;

}


void
on_move_endpos_button_clicked          (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = MOVE_END_POS;


}


void
on_next_play_button_clicked            (GtkButton       *button,
                                        gpointer         user_data)
{
	int i;

	for(i = 0; i < CAM_NUM; i++)
		p_play_info->state[i] = NEXT_PLAY;


}




void
on_search_dialog_realize               (GtkWidget       *widget,
                                        gpointer         user_data)
{
	int start, end, i;


	file_list = (GtkCList*)lookup_widget((GtkWidget*)widget, "file_list");
	
	start_combo[0] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "start_year_combo");
	start_combo[1] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "start_mon_combo");
	start_combo[2] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "start_day_combo");
	start_combo[3] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "start_hour_combo");

	end_combo[0] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "end_year_combo");
	end_combo[1] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "end_mon_combo");
	end_combo[2] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "end_day_combo");
	end_combo[3] = (GtkComboBox*)lookup_widget((GtkWidget*)widget, "end_hour_combo");

	for (i = 0; i < CAM_NUM; i++) {
		gtk_combo_box_set_active(start_combo[i], 0);
		gtk_combo_box_set_active(end_combo[i], 0);
	}

	start = 2006010100;
	end = 2030123124;

	set_file_info(file_list, start, end);

}



gboolean
on_draw_area_button_press_event        (GtkWidget       *widget,
                                        GdkEventButton  *event,
                                        gpointer         user_data)
{

	int ex, ey, mid_col, mid_row;
	int ecam_num;
	int i;

	ex = event->x;
	ey = event->y;
	mid_col = widget->allocation.width/2;
	mid_row = widget->allocation.height/2;

	if (event->type == GDK_2BUTTON_PRESS) {
		//g_print("x : %d y : %d width : %d, height : %d\n", ex, ey, mid_col, mid_row);
		if (area_view_mode == 2) {
			if (ex < mid_col) {
				if (ey < mid_row)
					ecam_num = 0;
				else
					ecam_num = 2;
			} else {
				if (ey < mid_row)
					ecam_num = 1;
				else
					ecam_num = 3;
			}
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen1), TRUE);
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_camera[ecam_num]), TRUE);
			area_view_mode = 1;
			for (i = 0; i < CAM_NUM; i++) {
				if (i == ecam_num )
					img_info[i].image_draw = 1;
				else
					img_info[i].image_draw = 0;
			}
		} else {
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_screen4), TRUE);
			area_view_mode = 2;
			for (i = 0; i < CAM_NUM; i++) 
				img_info[i].image_draw = 1;
		}
	}
  	return FALSE;
}


